package com.ayu.shortlink.settlement.util;

/**
 * 订单唯一生成器
 */
public class DistributedIdGenerator {
    /**
     * 起始时间戳 以2024年1月1号 0点0分0秒开始
     */
    private final Long EPOCH = 1704067200000L;
    private final Long NODE_ID;
    private final Long NODE_BITS = 5L;
    private final Long SEQUENCE_BITS = 7L;
    //上一个时间戳
    private Long lastStamp = -1L;
    //序列号
    private Long sequence = 0L;

    public DistributedIdGenerator(Long NODE_ID){
        this.NODE_ID = NODE_ID;
    }

    public synchronized Long generateID(){
        long timeStamp = System.currentTimeMillis() - EPOCH;
        //证明不合规
        if (timeStamp < lastStamp){
            throw new RuntimeException("该时间异常");
        }

        if (timeStamp == lastStamp){
            sequence = (sequence + 1) & ((1L << SEQUENCE_BITS) - 1 );
            if (sequence == 0L){
                //那么就可能会冲突 去重新生成
                timeStamp = tilNextMillis(lastStamp);
            }else {
                sequence = 0L;
            }

        }
        //生成完毕
        lastStamp = timeStamp;
        return (timeStamp << (NODE_BITS + SEQUENCE_BITS) | (NODE_ID << NODE_ID) | sequence);
    }

    private Long tilNextMillis(Long lastTimestamp) {
        long timestamp = System.currentTimeMillis() - EPOCH;
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis() - EPOCH;
        }
        return timestamp;
    }
}
